﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 单例模式
{

    /// <summary>
    /// 可多线程使用 
    /// </summary>
    class MultiThread_Singleton
    {

        //【关键字 volatile 】：类型修饰符，并且作为指令关键字，确保本条指令不会因为编译器的优化而省略
        /* 
         【特性】：实现可见性、实现有序性、实现原子性
         （1）、保证了不同的线程对这个变量进行操作时的可见性，即一个线程修改了某个变量的值，这个新值对其他的线程来说也是可见的。
         （2）、禁止进行指令的重排序
         （3）、只能保证对单次读写的原子性
        */

        //     关键字 volatile，如果去掉这个关键字，还是有可能发生线程不是安全的。 
        //     volatile 保证严格意义的多线程编译器在代码编译时对指令不进行微调

        private static volatile MultiThread_Singleton instance = null;

        private static object lockHelper = new object();


        /// <summary>
        /// 私有构造方法
        /// </summary>
        private MultiThread_Singleton()
        {

        }

        public static MultiThread_Singleton Instace
        {
            get
            {
                if (instance == null)
                {
                    //lock 关键字将语句块标记为临界区，方法是获取给定对象的互斥锁，执行语句，然后释放该锁。
                    lock (lockHelper)
                    {
                        if (instance == null)
                        {
                            //如果  instace 为空，保证只有一个线程创建唯一的一个实例
                            instance = new MultiThread_Singleton();
                        }
                    }
                }
                return instance;
            }

        }

    }
}
